/**
 * 定义群聊、私聊和特殊聊天室一些通用的方法和数据
 */
import {
	throttle
} from '@/utils/util.js'
// 引入清除会话未读数的方法
import {
	clearMessageUnreadStatus,
	getRongHistoryMessages
} from '@/utils/RongIM.js'

import moment from "moment";
export default {
	data() {
		return {
			// 显示名片详细信息弹窗变量
			showCardInfo: false,
			// 存入名片中的userId
			cardDetailInfo: {},
			// 判断最后一条是不是图文消息
			isLastImgMsg: false,
			// 判断页面是否加载完成
			stateTimer: '',
			initTimer: '',
			isLocalMsg: false,
			isBottomFinish: false,
			// 失去焦点时的位置
			blurIndex: 0,
			isInputFocus: false,
			// 多选的标识
			selectShow: false,
			// 多选的消息数据
			selectMsgItem: [],
			// 上一条播放语音的消息
			previousVodieMsg: null,
			innerAudioContext: null,
			vidieProgressTimer: null,
			isEmoji: false,
			WindowInfo: {},
			chatBoxStyle: {},
			onFocusTimer: null,
			allAudioContext: {},
			originHeight: 0,
			isRecord: false,
			bottomVal: 0,
			ifLongtap: true
		}
	},
	mounted() {
		const that = this
		// 解决ios切换不起作用的问题
		// that.iosInputFocusMethod()
    // #ifdef H5
		this.originHeight = document.documentElement.clientHeight || document.body.clientHeight;
		window.addEventListener('resize', this.handleResize);
    // #endif
	},
	beforeDestroy() {
    // #ifdef H5
		// 移除绑定的handleResize事件监听
		window.removeEventListener("resize", this.handleResize);
    // #endif
	},
	// 房间销毁前，清空会话未读数
	onHide() {
		this.stopPlayVoice()
		// clearMessageUnreadStatus(this.roomBaseInfo.targetId, this.roomBaseInfo.conversationType)
	},
	// onBackPress() {
	// 	const previewImageDom = document.getElementById('PreviewImage-mask')
	// 	if (previewImageDom) {
	// 		previewImageDom.remove();
	// 	}
	// 	console.log('返回键被点击了', )
	// },
	watch: {
		avatorIsShow: {
			handler(newVal, oldVal) {
				if (newVal.length !== oldVal?.length && newVal.length != 0) {
					newVal.forEach(t => {
						if (t.messageType === 'RC:HQVCMsg') {
							if (!this.allAudioContext[t.messageUId]) {
								this.$set(t.content, 'progress', 0)
								this.allAudioContext[t.messageUId] = uni.createInnerAudioContext()
								this.allAudioContext[t.messageUId].src = t.content.remoteUrl

								this.allAudioContext[t.messageUId].onPlay(() => {
									// 播放监听
									console.log('播放!');
								});

								this.allAudioContext[t.messageUId].onEnded(() => {
									setTimeout(() => {
										t.content.progress = 0
									}, 300)
									// 结束播放监听
									console.log('播放结束!');
								});

								this.allAudioContext[t.messageUId].onPause(() => {
									setTimeout(() => {
										t.content.progress = 0
									}, 300)
									// 结束播放监听
									console.log('播放暂停！');
								});

								this.allAudioContext[t.messageUId].onTimeUpdate(() => {
									const {
										currentTime,
										duration
									} = this.allAudioContext[t.messageUId]; //这俩参数是这个api自带的参数
									console.log('音频播放进度', currentTime, duration, t.content.duration);
									if (duration == Infinity) {
										t.content.progress = (currentTime / t.content.duration) * 100
									} else {
										t.content.progress = (currentTime / duration) * 100
									}
								});

								this.allAudioContext[t.messageUId].onError((e) => {
									setTimeout(() => {
										t.content.progress = 0
									}, 300)
									console.log('播放错误', e);
								})
							}
						}
					})
					console.log(this.allAudioContext, 'newValnewValnewValnewValnewVal');
				}
			},
			deep: true
		},
	},
	computed: {
		// 多选的消息ID
		selectMsgIds() {
			const arr = []
			// eslint-disable-next-line no-unused-expressions
			this.selectMsgItem?.forEach((item) => {
				arr.push(item.messageUId)
			})
			return arr
		},
		// 获取已读到消息的时间戳
		readTime() {
			let list = [...this.chatList]
			list = list.reverse()
			const newData = list.find(
				(t) => t.messageType === 'OL:ReadStatus' && t.messageDirection === 2
			)
			if (newData) {
				return newData.sentTime
			} else {
				return null
			}
		},
		// 过滤一些功能性消息
		fillterMessages() {
			console.log('未处理的聊天记录', this.chatList);
			return this.chatList?.filter(
				(t) => (t.messageType !== 'RC:RcCmd' && t.messageType !== 'OL:ReadStatus' && t.messageType !==
					'OL:Prerender' && t.messageType.indexOf('RC:VC') == -1) || (t.messageType === 'OL:Prerender' && t
					.senderUserId === this.$store.state.userInfo.userId)
			)
		}
	},
	onPageScroll(res) {
		if (uni.getSystemInfoSync().platform === 'ios') {
			setTimeout(() => {
				uni.pageScrollTo({
					scrollTop: 0,
					duration: 0,
				})
			}, 300)
		}
	},
	methods: {
		handleResize() {
			const resizeHeight = document.documentElement.clientHeight || document.body.clientHeight;
			if (resizeHeight < this.originHeight) {
				//当软键盘弹起，在此处操作
				if (uni.getSystemInfoSync().platform !== 'ios') {}
			} else {
				//当软键盘收起，在此处操作
				if (uni.getSystemInfoSync().platform !== 'ios') {
					setTimeout(() => {
						this.WindowInfo = uni.getWindowInfo()
					}, 200)
				}
			}
		},
		/**
		 * 避免滚动时触发longpress事件
		 */
		touchEnd() {
			this.ifLongtap = true;
		},
		touchMove() {
			this.ifLongtap = false;
		},
		// 点击空白处,收起弹窗
		clickBlank() {
			this.changeBottomType('none')
		},
		// 是否显示按住说的语音控件
		changeRecord(val) {
			this.inputBottomType = "none"
			this.isRecord = val
			if (!val) {
				this.isInputFocus = true
				// 解决ios切换不起作用的问题
				this.iosInputFocusMethod()
			}
		},
		// ios输入框聚焦失败原因
		iosInputFocusMethod() {
			if (uni.getSystemInfoSync().platform == 'ios') {
				this.$nextTick(() => {
					let rtn = ''
					const obj = this.$refs.scanTextbox.$el
					let currentObj = obj
					let index = 0
					while (!rtn && index < 3) {
						index++
						for (let i = 0; i < currentObj.childNodes.length; i++) {
							if (currentObj.childNodes[i].tagName == "INPUT") {
								rtn = currentObj.childNodes[i];
								break
							}
						}

						currentObj = obj.childNodes[0]
					}
					rtn.focus()
				})
			}
		},
		// 点击工具栏事件
		changeBottomType(type) {
			if (this.selectShow) return;
			if (this.inputBottomType == "none" && type == "none") {
				return
			}
			if (this.inputBottomType == type) {
				this.inputBottomType = "none";
			} else {
				this.isRecord = false
				this.inputBottomType = type;
				if (uni.getSystemInfoSync().platform !== 'ios') {
					if (type == 'emoji') {
						this.isEmoji = true
						this.foucusInputWithoutKeyboard()
					}
				}
			}
			this.scrollToBottom()
		},
		// scrollMsg: throttle(() => {
		// 	uni.hideKeyboard()
		// }, 500),
		// 播放语音功能
		playVoice(item) {
			if (this.selectShow) return
			// 如果点击正在播放中的语音,则暂停播放
			const isCurentAudioPaused = this.allAudioContext[item.messageUId].paused
			this.stopPlayVoice(item.messageUId)
			if (!isCurentAudioPaused) return
      try{
        this.allAudioContext[item.messageUId].currentTime = 0
      }catch(e){}
      this.$nextTick(() => {
        this.allAudioContext[item.messageUId].play() 
      })
		},
		// 暂停语音播放
		stopPlayVoice(current) {
			for (const key in this.allAudioContext) {
        if(current !== key) {
          this.allAudioContext[key].pause()
        }
			}
			// if (this.allAudioContext[messageUId]) {
			// 	this.allAudioContext[messageUId]
			// 	this.allAudioContext[messageUId].stop()
			// }
		},
		// 多选操作
		selectMsgHandle(item) {
			if (this.selectMsgItem.length === 0) {
				this.selectMsgItem.push(item)
			} else {
				let index = -1
				this.selectMsgItem.find((t, i) => {
					if (item.messageUId === t.messageUId) {
						index = i
					}
					return item.messageUId === t.messageUId
				})
				if (index === -1) {
					this.selectMsgItem.push(item)
				} else {
					this.selectMsgItem.splice(index, 1)
				}
			}
		},
		/**
		 * 判断字符串里是否存在标签，并提取标签中的str
		 * @param str 需要复制的内容
		 * @return OBJ {result: true, str: ''}
		 */
		isHTML(str) {
			const res = {
				result: false,
				str: ''
			}
			var a = document.createElement('div')
			a.innerHTML = str

			for (var c = a.childNodes, i = c.length; i--;) {
				if (c[i].nodeType == 1) {
					res.result = true
					res.str = c[i].innerHTML
					return res
				}
			}
			return res
		},
		// 复制功能
		onCopyMsg(item) {
			let str = item.content.content
			const isHtml = this.isHTML(str)
			if (isHtml.result) {
				str = isHtml.str
			}
			switch (item.messageType) {
				case 'RC:TxtMsg':
				case 'OL:Recall':
					uni.setClipboardData({
						data: str,
						success: function() {
							console.log('success');
						}
					});
					break;
				default:
					break;
			}
		},
		/*H5录音失败*/
		recorderError(e) {
			if (e) {
				uni.showToast({
					title: e,
					icon: 'error'
				});
			}
			setTimeout(() => {
				this.recorderManagerOpen = false
			}, 300)
			if (this.timer) {
				clearInterval(this.timer);
				this.timer = undefined;
			}
		},
		/*H5录音成功*/
		async recorderSuccess(e) {
			//console.log('recorderSuccess', e);
			var sec = moment().diff(this.startTime, 'seconds');
			console.log('H5录音成功', e, e.duration, sec);
			// if (this.isCancel) {
			// 	uni.showToast({
			// 		title: '已取消',
			// 		icon: 'success'
			// 	});
			// 	this.isCancel = false;
			// 	return;
			// }
			if (sec < 1) {
				return;
			}

			const res = await this.uploadFilePromise(2, e.localUrl, "", sec);
			console.log(res, 'res');
		},
		// 表情选择功能
		selectEmoji(item) {
			this.isInputFocus = false
			this.isEmoji = true
			const index = this.blurIndex
			const str = this.messageContent
			this.messageContent = str.slice(0, index) + item.emoji + str.slice(index)
			setTimeout(() => {
				this.blurIndex = this.blurIndex + item.emoji.length

				if (uni.getSystemInfoSync().platform !== 'ios') {
					this.foucusInputWithoutKeyboard()
				}
				console.log(this.blurIndex, 545665);
			}, 140)
		},
		clickInput() {
			if (uni.getSystemInfoSync().platform !== 'ios') {
				this.inputBottomType = "none";
				this.isInputFocus = true
			}
		},
		// 表单获取焦点
		async typingInputFocus(event) {
			const systemInfo = uni.getSystemInfoSync()
			this.isInputFocus = true
			const that = this
			const isTools = this.inputBottomType != "none"
			if (systemInfo.platform === 'ios') {
				this.WindowInfo = uni.getWindowInfo() 
				if (that.bottomVal == 0) {
					const inputBottomTypeCopy = that.inputBottomType
					setTimeout(() => {
						let viewInfo = this.$refs.wrapper.$el.getBoundingClientRect()
						if (inputBottomTypeCopy == 'emoji') {
							that.WindowInfo.windowHeight -= Math.abs(parseFloat(viewInfo.top))
						} else {
							that.bottomVal = Math.abs(parseFloat(viewInfo.top))
							that.WindowInfo.windowHeight -= that.bottomVal
						}
						scrollTo(0, 0)
						this.scrollToBottom()
						console.log(that.bottomVal, 'bottomValbottomValbottomVal');
					}, 200)
				} else {
					this.WindowInfo.windowHeight -= that.bottomVal
					scrollTo(0, 0)
					this.scrollToBottom()
				}
			} else {
				setTimeout(() => {
					this.WindowInfo = uni.getWindowInfo()
					this.scrollToBottom()
				}, 300)
			}

			if (systemInfo.platform !== 'ios') {
				if (this.isEmoji) {
					this.isEmoji = false
				} else {
					this.inputBottomType = "none";
				}
			} else {
				this.inputBottomType = "none";
			}
		},
		// 表单失去焦点
		typingInputBlur(event) {
			setTimeout(() => {
				this.WindowInfo = uni.getWindowInfo()
			}, 200)
			this.chatBoxStyle = null
			this.blurIndex = event.target.cursor
			this.isInputFocus = false
		},
		// 输入框聚焦,但是不显示软键盘方法
		foucusInputWithoutKeyboard() {
      // #ifdef H5
      
			this.$nextTick(() => {
				this.isInputFocus = true
				let rtn = ''
				const obj = this.$refs.scanTextbox.$el

				let currentObj = obj
				let index = 0
				while (!rtn && index < 3) {
					index++
					for (let i = 0; i < currentObj.childNodes.length; i++) {
						if (currentObj.childNodes[i].tagName == "TEXTAREA") {
							rtn = currentObj.childNodes[i];
							break
						}
					}

					currentObj = obj.childNodes[0]
				}
				console.log(rtn);

				console.log(this.blurIndex, 54566511111);
				rtn.setAttribute('readonly', 'readonly');
				setTimeout(() => {
					rtn.removeAttribute('readonly');
				}, 100);

			})

      // #endif
		},
		// 回复消息点击回调
		locateToRecall(msgInfo) {
			// console.log(this.$refs['room-msgs'].offsetHeight)
			const target = document.getElementById('S-' + msgInfo.messageUId)
			if (target) {
				target.parentNode.parentNode.scrollTop = target.offsetTop - 300
			} else {
				this.isBottomFinish = false
				this.isFinish = false
				this.getLocalHistoryMsg(msgInfo)
			}
			console.log('回复的信息', target, msgInfo.sentTime)
		},
		// 获取指定位置的聊天信息
		async getLocalHistoryMsg(msgInfo) {
			const suffixData = await getRongHistoryMessages(
				this.roomBaseInfo?.targetId,
				this.roomBaseInfo?.conversationType,
				msgInfo.sentTime - 1,
				1
			)
			const prefixData = await getRongHistoryMessages(
				this.roomBaseInfo?.targetId,
				this.roomBaseInfo?.conversationType,
				msgInfo.sentTime
			)
			this.chatList = [...prefixData, ...suffixData]
			this.$nextTick(() => {
				const target = document.getElementById(msgInfo.messageUId)
				target.parentNode.parentNode.scrollTop = target.offsetTop - 300
			})
			this.isLocalMsg = true
			console.log('获取指定数据', prefixData, suffixData)
		},
		async getBelowHistoryMsg(msgInfo) {
			console.log(msgInfo, 'msgInfo')
			const suffixData = await getRongHistoryMessages(
				this.roomBaseInfo?.targetId,
				this.roomBaseInfo?.conversationType,
				msgInfo.sentTime,
				1
			)
			if (suffixData.length < 20) {
				this.isBottomFinish = true
			}
			console.log('之后的数据', suffixData)
			this.chatList = [...this.chatList, ...suffixData]
		},
		// 图片加载成功时间
		handleLoadImg(todo) {
			if (this.isLastImgMsg) {
				this.scrollToBottom()
				this.isLastImgMsg = false
				console.log('图片加载状态', todo, this.imgList.length)
			}
		},
		// 点击撤回信息,等同于删除双方的信息
		handleRecallMessage(msg, ConversationType) {
			const that = this
			const extra = {
				latestMessage: {}
			}
			const filterMsg = that.fillterMessages.filter(
				(item) => item.messageUId !== msg.messageUId
			)
			if (filterMsg.length > 0) {
				extra.latestMessage = filterMsg[filterMsg.length - 1]
			}
			const conversation = {
				conversationType: ConversationType,
				targetId: msg.targetId
			}
			const options = {
				messageUId: msg.messageUId,
				sentTime: msg.sentTime,
				extra // 用户
			}
			this.$RongIMLib
				.recallMessage(conversation, options)
				.then((res) => {
					if (res.code === 0) {
						this.$store.dispatch('updateChatList', {
							data: res.data,
							type: 'recall'
						})
						console.log(res.code, res.data)
						const findData = that.chatList.find(
							(item) => item.messageUId === msg.messageUId
						)
						findData.messageType = 'RC:RcCmd'
					} else {
						console.log(res.code, res.msg)
					}
				})
				.catch((error) => {
					console.log(error)
				})
		},
		// 群聊点击头像显示卡片信息
		onClickUserImage(item) {
			if (this.selectShow) return
			this.cardDetailInfo = item.senderUserId
			this.showCardInfo = true
		},
		// 点击名片回调
		onCardView(item) {
			if (this.selectShow) return
			this.cardDetailInfo = item.content.info.userId
			this.showCardInfo = true
			console.log('名片信息', item)
		},
		// 发送已读消息
		sendReadTimeMsg(data, conversationType, targetId) {
			if (data.length === 0) {
				return
			}
			let lastMsg = [...data]
			lastMsg = lastMsg[lastMsg.length - 1]
			if (
				lastMsg.messageType !== 'OL:ReadStatus' &&
				lastMsg.messageDirection === 2 &&
				lastMsg.messageType.indexOf('RC:VC') == -1
			) {
				this.setReadTimeMsg(
					conversationType,
					targetId,
					lastMsg
				)
			}
		},
		// 发送已读消息实例
		async setReadTimeMsg(conversationType, targetId, preMsg) {
			const createLastMsg = {
				latestMessage: preMsg
			}
			const conversation = {
				conversationType: conversationType,
				targetId: String(targetId)
			}
			const timestamp = new Date().getTime()
			const options = {
				messageId: timestamp
			}
			const message = new this.$RongIMLib.ReadStatusMessage({
				content: timestamp,
				preMsg: createLastMsg
			})
			const res = await this.$RongIMLib.sendMessage(
				conversation,
				message,
				options
			)
			if (res.code === this.$RongIMLib.ErrorCode.SUCCESS) {
				console.log('发送已读状态消息成功')
			} else {
				console.log('发送已读状态失败')
			}
		},
		// 发送自己再输入中的状态消息
		_sendTypingStatusMessage: throttle(function(conversationType, targetId) {
			this.$RongIMLib.sendTypingStatusMessage({
					conversationType,
					targetId
				},
				this.$RongIMLib.MessageType.TEXT
			)
		}, 600),

		// 处理发送消息失败的提示语
		sendMsgError(code, msg, data) {
			switch (code) {
				case 22408:
					uni.showToast({
						title: this.$t('chat.banedTip'),
						icon: "none",
						duration: 2000
					});
					// this.roomBaseInfo.info.groupStatus = 1
					this.messageContent = ''
					this.isInputFocus = false
					break
				case 405:
					uni.showToast({
						title: this.$t('chat.black-tip'),
						icon: "none",
						duration: 2000
					});
					data.isOppositeBlockUser = 1
					this.messageContent = ''
					this.isInputFocus = false
					break
				default:
					uni.showToast({
						title: msg,
						icon: "none",
						duration: 2000
					});
					break
			}
		},
		// 滚动到底部触发事件
		scrollToBottomLoad() {
			if (this.isLocalMsg && !this.isBottomFinish) {
				this.getBelowHistoryMsg(this.chatList[this.chatList.length - 1])
				console.log('滚动到底部啦！！')
			}
		},
		// 获取网址
		getLinkTextToHtml(msg) {
			console.log(msg)
			const urlRegex = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gi
			return msg.replace(urlRegex, (url) => {
				// return `<a href="${url}" target="_blank" class="a-link">${url}</a>`
				return `<span onclick="window.open('${url}')" class="a-link">${url}</span>`
			})
		},
		setPreRenderMsg(obj, conversationType, targetId, msg) {
			const timestamp = new Date().getTime()
			// 定义消息投送目标会话
			const conversation = {
				conversationType: conversationType,
				targetId: String(targetId)
			}

			// 配置属性
			const options = {
				messageId: timestamp,
				canIncludeExpansion: msg != '',
				expansion: {
					content: msg
				}
			}

			const message = new this.$RongIMLib.PreRenderMessage({
				content: '',
				info: obj
			})

			return this.sendMessage(conversation, message, options)
		},
		// 识别文件类型
		identifyFileType(filename) {
			// 根据文件名返回对应文件类型
			let type = "unknown";
			if (!filename) return type;
			const index = filename.lastIndexOf(".");
			let extension = filename.substr(index + 1).toLowerCase();
			extension = extension.split("?")[0];
			const typeMap = {
				img: [
					"gif",
					"jpg",
					"jpeg",
					"png",
					"bmp",
					"webp",
					"ico",
					"psd",
					"svg",
					"tiff",
				],
				video: [
					"mp4",
					"m3u8",
					"rmvb",
					"avi",
					"swf",
					"3gp",
					"mkv",
					"flv",
					"VIDEO",
				],
				audio: ["mp3", "wav", "wma", "ogg", "aac", "flac"],
				doc: ["doc", "docx", "pages", "epub", "numbers", "keynote", "km"],
				// document: ['doc', 'txt', 'docx', 'pages', 'epub', 'pdf', 'numbers', 'csv', 'xls', 'xlsx', 'keynote', 'ppt', 'pptx']
				ppt: ["ppt", "pptx"],
				xls: ["csv", "xls", "xlsx"],
				pdf: ["pdf"],
				mind: ["km", "mm", "mmap", "xmind"],
				zip: ["rar", "zip", "7z", "jar", "gz"],
				txt: ["txt"],
			};
			Object.keys(typeMap).forEach((_type) => {
				const extensions = typeMap[_type];
				if (extensions.indexOf(extension) > -1) {
					type = _type;
					return type;
				}
			});
			return type;
		},
	}
}